package com.lg.atp.controller;

import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.sql.Timestamp;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.io.FileUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartRequest;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.lg.atp.entity.CaseRunStepResult;
import com.lg.atp.entity.TblAppInfo;
import com.lg.atp.entity.TblAttachment;
import com.lg.atp.entity.TblCaseStep;
import com.lg.atp.entity.TblTestAttachment;
import com.lg.atp.entity.TblTestTask;
import com.lg.atp.entity.TblTestTaskCaseRunWithBLOBs;
import com.lg.atp.service.IAppInfoService;
import com.lg.atp.service.IAttachmentService;
import com.lg.atp.service.ITCaseRunStepResultService;
import com.lg.atp.service.ITCaseStepService;
import com.lg.atp.service.ITaskCaseRunService;
import com.lg.atp.service.ITaskService;
import com.lg.atp.service.ITestAttachmentService;
import com.lg.atp.service.ScriptService;
import com.lg.atp.utils.DeviceConstants;
import com.lg.atp.utils.PictureTool;

@RestController
@RequestMapping("wsServices")
public class WSController {
	
	private Log log = LogFactory.getLog(WSController.class);
	
	private @Value("${targetFilePath}") String targetFilePath;
	
	private @Value("${attachmentUrl}") String attachmentUrl;
	
	@Autowired
	private IAppInfoService iAppInfoService;
	
	@Autowired
	private IAttachmentService IAttachmentService;
	
	@Autowired
	private ITaskCaseRunService iTaskCaseRunService;
	@Autowired
	private ITaskService iTaskService;
	
	@Autowired
	private ITCaseStepService iTCaseStepService;
	
	@Autowired
	private ITCaseRunStepResultService iTCaseRunStepResultService;
	
	@Autowired
	private ITestAttachmentService iTestAttachmentService;
	
	@Autowired
	private ScriptService scriptService;
	

	@GetMapping("getScript/{scriptId}")
		public void getScript(HttpServletResponse resp,@PathVariable String scriptId) {
			resp.reset();
			TblAttachment attachment=null;
			OutputStream os = null;
			try {
				os = resp.getOutputStream();
				if (scriptId.endsWith(".md5sum")) {
					scriptId=scriptId.replace(".md5sum", "");
					attachment=IAttachmentService.selectFileById(Long.valueOf(scriptId));
					File file = new File(attachment.getFilePath());
					resp.setHeader("Content-Disposition", "attachment;filename="+file.getName());
					String md5Hex = DigestUtils.md5Hex(new FileInputStream(file));
					os.write(md5Hex.getBytes());
				}else {
					attachment=IAttachmentService.selectFileById(Long.valueOf(scriptId));
					File file = new File(attachment.getFilePath());
					resp.setHeader("Content-Disposition", "attachment;filename="+file.getName());
					byte[] buffs =FileUtils.readFileToByteArray(file);
					os.write(buffs);
				}
			} catch (IOException e) {
				e.printStackTrace();
			} finally {
				if (os != null) {
					try {
						os.close();
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
			}
		}
		
	@GetMapping("getScriptCode/{scriptId}")
	public void getScriptCode(@PathVariable Long scriptId) {
		//scriptService.generateScriptByCaseId(scriptId, 1);
	}
	@GetMapping("cropBase/{uuid}")
	public void recording(HttpServletResponse resp,@PathVariable String uuid) {
		OutputStream os = null;
		try {
			os = resp.getOutputStream();
		String targetFile = targetFilePath+"temp/"+uuid+".png";
		String afterBase64 = PictureTool.GetImageStr(targetFile);
		//PictureTool.crop(source, startX, startY, endX, endY);
	    //byte[] buffs =FileUtils.readFileToByteArray(outFile);
		//os.write(buffs);
		os.write(afterBase64.getBytes());
		}catch (Exception e) {
			// TODO: handle exception
		}finally{
			if (os != null) {
				try {
					os.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		};
	}
	@PostMapping("getQuestionResolution")
	public void getQuestionResolution(HttpServletResponse resp,String source,Integer startX,Integer startY,Integer endX,Integer endY,String seachString){ 
		String regex = seachString+"([\\s\\S]*)]\""; 
		String regex2 = "bounds\":\"\\[([\\s\\S]*?)]\""; 
		source = source.trim().replaceAll("=\"", "\":\"");
		Matcher matcher = Pattern.compile(regex).matcher(source);
		Integer targetX = null;
		Integer targetY = null;
		boolean flag = true;
		while(flag){
			if (matcher.find()) {

				source = matcher.group(1).trim();

				Matcher matcher2 = Pattern.compile(regex2).matcher(source);
				if (matcher2.find()) {
					String bbbb= matcher2.group(1); 
					String[] tabs =bbbb.split("\\]\\[");
					String[] tabStreat = tabs[0].split(",");
					String[] tabEnd = tabs[1].split(",");
					Integer targetTempX = (Integer.valueOf(tabStreat[0])+Integer.valueOf(tabEnd[0]))/2;
					Integer targetTempY = (Integer.valueOf(tabStreat[1])+Integer.valueOf(tabEnd[1]))/2;
					if (targetTempX>=startX&&targetTempY>=startY&&targetTempX<=endX&&targetTempY<=endY) {
						targetX = targetTempX;
						targetY = targetTempY;
						flag=false;
					}
					
				}
				matcher = Pattern.compile(regex).matcher(source);
			}else {
				flag=false;
			}
		}
		OutputStream os = null;
		try {
			os = resp.getOutputStream();
			os.write((targetX+","+targetY).getBytes());
		}catch (Exception e) {
		}finally{
			if (os != null) {
				try {
					os.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	} 
	
	@POST
	@Produces(MediaType.TEXT_PLAIN)
	@Consumes(MediaType.MULTIPART_FORM_DATA)
	@RequestMapping(value = "crop/{x}/{y}/{w}/{h}/{uuid}", method = RequestMethod.POST)
	//@PostMapping("crop/{x}/{y}/{w}/{h}/{base64}")
	public void crop(HttpServletResponse resp,MultipartFile file,
			MultipartRequest aaaa,
			@PathVariable int x,
			@PathVariable int y,
			@PathVariable int w,
			@PathVariable int h,
			@PathVariable String uuid) {
		Map<String, MultipartFile>  map = aaaa.getFileMap();
		
		MultipartFile file1 = map.get("attachments");
		//resp.reset();
		OutputStream os = null;
		try {
			os = resp.getOutputStream();
			String path = targetFilePath+"temp/" + file1.getOriginalFilename();
	         File sourceFile =  new File(path);

	             FileUtils.copyInputStreamToFile(file1.getInputStream(), sourceFile);
			//String sourceFilePath = targetFilePath+"temp/"+UUID.randomUUID()+".png";
			String targetFile = targetFilePath+"temp/"+uuid+".png";
		     BufferedImage imageFirst = ImageIO.read(sourceFile);
		     //float bill = ((float)(imageFirst.getHeight())/(float)500);
		     imageFirst=PictureTool.crop(imageFirst, x, y, w, h);
			File outFile = new File(targetFile);
		    ImageIO.write(imageFirst, "png", outFile);// 写图片
		    String afterBase64 = PictureTool.GetImageStr(targetFile);
			//PictureTool.crop(source, startX, startY, endX, endY);
		    //byte[] buffs =FileUtils.readFileToByteArray(outFile);
			//os.write(buffs);
		    //resp.setHeader("Content-Disposition", "attachment;filename="+file.getName());
			os.write(afterBase64.getBytes());
			
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (os != null) {
				try {
					os.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
	
	@GetMapping("getappById/{projectAppId}")
	public void getappById(HttpServletResponse resp,@PathVariable String projectAppId) {
		resp.reset();
		TblAttachment attachment=null;
		OutputStream os = null;
		try {
			os = resp.getOutputStream();
			if (projectAppId.endsWith(".md5sum")) {
				projectAppId=projectAppId.replace(".md5sum", "");
				TblAppInfo appInfo = iAppInfoService.selectAppById((long) Integer.parseInt(projectAppId));
				attachment=IAttachmentService.selectFileById(appInfo.getAttachmentId());
				File file = new File(attachment.getFilePath());
				resp.setHeader("Content-Disposition", "attachment;filename="+file.getName());
				String md5Hex = attachment.getFileNameNew();
				os.write(md5Hex.getBytes());
			}else {
				TblAppInfo appInfo = iAppInfoService.selectAppById((long) Integer.parseInt(projectAppId));
				attachment=IAttachmentService.selectFileById(appInfo.getAttachmentId());
				File file = new File(attachment.getFilePath());
				resp.setHeader("Content-Disposition", "attachment;filename="+file.getName());
				byte[] buffs =FileUtils.readFileToByteArray(file);
				os.write(buffs);
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (os != null) {
				try {
					os.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
	
	
	/**
	 * http://localhost:8080/demo/page/jsp/device/test.jsp页面进行测试
	 * matc系统根据我们返回的错误码是否是200来决定是否上传结果成功
	 * 
	 * @param body
	 * @param caseId
	 * @param caseResultId
	 * @return
	 * @throws Exception
	 */
	@POST
	@Produces(MediaType.TEXT_PLAIN)
	@Consumes(MediaType.MULTIPART_FORM_DATA)
	@RequestMapping(value = "getresultById/{caseId}/{caseResultId}", method = RequestMethod.POST)
	//@GetMapping("getresultById/{caseId}/{caseResultId}")
	public  String result(HttpServletResponse resp, MultipartFile file,MultipartRequest aaaa,
			@PathVariable String caseId,
			@PathVariable String caseResultId) throws Exception {

		//List<Attachment> allAttachments = body.getOriginalFilename();

		Map<String, MultipartFile>  map = aaaa.getFileMap();
		
		MultipartFile file1 = map.get("attachments");
		
		String filePath = attachmentUrl;
		File files = new File(filePath);
		 if(! files.exists()) {
			 files.mkdir();
         }
		 String path = filePath + file1.getOriginalFilename();
         File tempFile = null;
         try {
             tempFile =  new File(path);

             FileUtils.copyInputStreamToFile(file1.getInputStream(), tempFile);
             
             ZipFile zipFile = new ZipFile(path);

     		// 获取result.json文件，并解析
     		ZipEntry jsonFile = zipFile.getEntry(DeviceConstants.AUTO_RESULT_JSON);

     		log.info("jsonFile----" + jsonFile.getName());
     		if (jsonFile != null) {
     			InputStream inputStream = zipFile.getInputStream(jsonFile);
     			InputStreamReader isr = new InputStreamReader(inputStream,"UTF-8");//读取    
     	        //创建字符流缓冲区    
     	        BufferedReader bufr = new BufferedReader(isr);//缓冲    
     	        StringBuffer result = new StringBuffer();
     	        String line = null;  
     	        while ((line = bufr.readLine()) != null) {  
     	            result.append(System.lineSeparator()+line);  
     	        }  
     	        isr.close();  
     	        
     	        
     	       //List<JobResult> returnList = JSONObject.parseArray(result.toString(), JobResult.class);
     	        
     	       
     	      JSONObject JSONObject = JSON.parseObject(result.toString());
     	      JSONArray jobStep = JSONObject.getJSONArray("Steps");
     	      List<TblCaseStep> list = iTCaseStepService.selectStepByCaseId(Long.valueOf(caseId));
     	      TblTestTaskCaseRunWithBLOBs caseRun =  iTaskCaseRunService.selectByTaskCaseRunId(Integer.parseInt(caseResultId));
     	      caseRun.setTestTaskRunStatus(JSONObject.get("status").toString()=="passed"?3L:4L);
     	      caseRun.setErrorMessage(JSONObject.get("Case_error_message").toString());
     	      iTaskCaseRunService.updateByTaskCaseRunIdWithBLOBs(caseRun);
     	      
     	      for (int i = 0; i < jobStep.size(); i++) {  
                 JSONObject jo = jobStep.getJSONObject(i);  
                 CaseRunStepResult stepResult = new CaseRunStepResult();
                 stepResult.setErrorMessage(jo.getString("error_message"));
                 stepResult.setTestResult(jo.getString("stepResult")=="true"?1:2);
                 stepResult.setCaseStepId(Integer.parseInt(list.get(i).getId().toString()));
                 stepResult.setTestTaskCaseRunId(caseRun.getId());
                 stepResult.setOperateControlId(list.get(i).getOperateControlId()==null?null:Integer.parseInt(list.get(i).getOperateControlId().toString()));
                 stepResult.setOperateType(list.get(i).getOperateType());
                 stepResult.setOperateReadParaId(list.get(i).getOperateReadParaId());
                 stepResult.setOperateReadRule(list.get(i).getOperateReadRule());
                 stepResult.setOperateWriteParaId(list.get(i).getOperateWriteParaId());
                 stepResult.setWaitingSecs(list.get(i).getWaitingSecs());
                 stepResult.setExpectType(list.get(i).getExpectType());
                 stepResult.setExpectControlId(list.get(i).getExpectControlId()==null?null:Integer.parseInt(list.get(i).getExpectControlId().toString()));
                 stepResult.setExpectParaOperation(list.get(i).getExpectParaOperation());
                 String pictureName = jo.getString("shotName");
					if(!StringUtils.isEmpty(pictureName)&&!"null".equals(pictureName)){
						String[] picture = pictureName.split("\\.");
						ZipEntry pictureFile =null;
						if (picture.length>1) {
							pictureFile = zipFile.getEntry("sample/screenshot/"+picture[0].substring(0, picture[0].length()-1)+"."+DeviceConstants.FILE_TYPE_PNG);
						}
						if(pictureFile!=null){
							inputStream = zipFile.getInputStream(pictureFile);
							//图片保存路径
							String timeString = new Date().getTime()+"";
							String stepPicturePath = filePath ;
							FileUtils.copyInputStreamToFile(inputStream, new File(
									stepPicturePath + "/" + timeString+"."+DeviceConstants.FILE_TYPE_PNG));

							TblTestAttachment testCaseResultAttachment = this
									.createNewAttachment(timeString+"."+DeviceConstants.FILE_TYPE_PNG,
											stepPicturePath+ timeString+"."+DeviceConstants.FILE_TYPE_PNG,
											DeviceConstants.FILE_TYPE_PNG);

							File pictureFilePath = new File(stepPicturePath+ "/" + timeString +"."+DeviceConstants.FILE_TYPE_PNG);

							BufferedImage image = ImageIO.read(pictureFilePath);

							int width = image.getWidth();

							int height = image.getHeight();

							if (height < width) {
								stepResult.setIsHorizontal(1);
							}else{
								stepResult.setIsHorizontal(1);
							}
							stepResult.setTestAttachmentId(testCaseResultAttachment.getId());

						}else{
							stepResult.setIsHorizontal(1);
						}
					}
                 iTCaseRunStepResultService.insertResult(stepResult);
                 
              }  
     	     int count = iTaskCaseRunService.selectSuccesRunCountByTaskId(caseRun.getTestTaskId());
     	     if(count==0){
     	    	 TblTestTask testTask = iTaskService.getTaskById(caseRun.getTestTaskId());
     	    	 testTask.setTestStatus(3);
     	    	 iTaskService.updateTestTask(testTask);
     	     }else{
     	    	TblTestTask testTask = iTaskService.getTaskById(caseRun.getTestTaskId());
    	    	 testTask.setTestStatus(2);
    	    	 iTaskService.updateTestTask(testTask);
     	     }
     		}
         }catch (Exception e) {
        	 e.printStackTrace();
         }
		return filePath;
	}
	
	public TblTestAttachment createNewAttachment(String fileName, String path,
			String fileType) {
		TblTestAttachment tblTestAttachment = new TblTestAttachment();
		tblTestAttachment.setCreateTime(new Timestamp(System
				.currentTimeMillis()));
		tblTestAttachment.setFileNameNew(fileName);
		tblTestAttachment.setFileNameOld(fileName);
		tblTestAttachment.setFilePath(path);
		tblTestAttachment.setFileType(fileType);
		iTestAttachmentService.insertTestAttachment(tblTestAttachment);
		return tblTestAttachment;
	}

}
